springboot post-processor应用在beanDefinition转为beanInstance再为proxy类草录

前提

如果你已经很了解springbooot中bean post-processor的原理和使用,本文向你展示了一个精简版和可视化图谱;如果你很想了解它,本文提供你梯子快速的走入bean post-processor原理和应用。以减少你原本需要花费的时间
本文的结构为图+文本结合的方式阐述

知识点收获

通过本文,你能收获什么?

  1. BeanPostProcessor作用
  2. BeanPostProcessor中其每个方法的应用场景
  3. BeanPostProcessor家族成员
  4. BeanPostProcessor类型对象在spring ioc时的应用

图中展示了spring(boot)中post-processor应用在BeanDefinition转为BeanInstance再为Proxy代理类整体的流程,包括哪个方法应用了具体的哪个post-processor,以达到什么目的或作用。

看完图中的图例后再看正图
springboot post-processor应用在 BeanDefinition转为BeanInstance再为Proxy代理类.png

正文

现在,我们结合图的基础上,阐述eanPostProcessor的家族和使用

BeanPostProcessor作用

BeanPostProcessorspring框架中非常重要的类,每一个放到spring ioc中的bean的创建过程都有他的身影。俗称前置处理和后置处理,意思为在bean的创建前后可以增加自定义的处理逻辑。如,bean创建前给某个类型的bean增加一个属性值,在bean创建后生成这个bean的代理类放到spring ioc中等等

注意: BeanPostProcessor是在spring容器加载了bean的定义文件并且实例化bean之后执行的BeanPostProcessor的执行顺序是在BeanFactoryPostProcessor之后。关于BeanPostProcessor vs BeanFactoryPostProcessor,参见BeanFactoryPostProcessory与BeanPostProcessor区别

BeanPostProcessor中其每个方法的应用场景

BeanPostProcessor类结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public interface BeanPostProcessor {
/**
*
* populate beans via marker interfaces
*
* 应用时机:after populate property values and before any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method)
*
* 应用场景:我的理解为给bean属性赋值的场景下使用
*
* 如:ServletContextAwareProcessor
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

/**
* 经常用于生成proxy代理类,如应用在FactoryBean
*
* 应用时机:after any bean initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method)
* 应用场景:经常用于生成proxy代理类,如应用在FactoryBean
*
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}

BeanPostProcessor有个经常使用的子类型:InstantiationAwareBeanPostProcessor,看其结构

InstantiationAwareBeanPostProcessor比BeanPostProcessor多的功能是:adds a before-instantiation callback, and a callback after instantiation but before explicit properties are set or autowiring occurs

典型的使用场景如 create proxies with special TargetSources (pooling targets, lazily initializing targets, etc), or to implement additional injection strategies such as field injection

InstantiationAwareBeanPostProcessor比BeanPostProcessor多了三个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

/**
* 应用时机:before populate property values
* 应用场景:已知的场景是aop生成TargetSource的proxy代理类。todo 准确的应用
*
*/
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}

/**
* 应用时机:Perform operations after the bean has been instantiated,
* but before Spring property population (from explicit properties or autowiring) occurs
*
* 应用场景:performing custom field injection on the given bean instance, right before Spring's autowiring kicks in
*/
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}

/**
* 应用时机:postProcessAfterInstantiation之后
* 应用场景:都是直接return true
*/
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {

return null;
}
}

从开篇的图中可看出,bean的创建(beanDefinition->beanInstance->proxy)与post-processor紧密的交织在一起。如何正确的使用他们成为难点和关键点

BeanPostProcessor家族成员

20191201203038.png

Spring中内置了很多的BeanPostProcessor实现类,列举的都是我们熟悉的,他们给出了很好的使用例子,为我们使用BeanPostProcessor去实现我们的自己场景和应用提供了参考的姿势

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
BeanPostProcessor
--ConfigurationPropertiesBindingPostProcessor 参数绑定相关的应用
--ConfigurationPropertiesBeans 参数绑定相关的应用

--ApplicationContextAwareProcessor 用来为bean注入ApplicationContext等容器对象
--AsyncAnnotationBeanPostProcessor @Async注解解析应用

--DataSourceInitializerPostProcessor dataSource相关应用

--BeanValidationPostProcessor bean的校验相关应用
--MethodValidationPostProcessor method的校验相关应用

--KafkaListenerAnnotationBeanPostProcessor kafka监听器的使用

--InstantiationAwareBeanPostProcessor 增加了before-instantiation和after instantiation的callback
----CommonAnnotationBeanPostProcessor:支持@Resource注解的注入
----AutowiredAnnotationBeanPostProcessor:支持@Autowired注解的注入
----InstantiationAwareBeanPostProcessorAdapter 对外暴露的InstantiationAwareBeanPostProcessor
----AnnotationAwareAspectJAutoProxyCreator 专门处理@AspectJ注解的
----ImportAwareBeanPostProcessor

典型的应用示例

AutowiredAnnotationBeanPostProcessor

由你来完成

it`s time to summary

开篇图几个BeanPostProcessor子类型与bean创建的交互关系,通过它你可以很明晰的了解到post-processorbean创建的不同阶段应用的方法。相信对你了解bean的创建提供了很好的可视化
;同时,文中详述了BeanPostProcessorInstantiationAwareBeanPostProcessorBeforeInstantiation、AfterInstantiation、BeforeInitialization、AfterInitialization、postProcessProperties方法的应用场景和应用时机,希望可以引导出合适的使用姿势
;最后,列举了常用的BeanPostProcessor实现类型,简述了主要使用场景。每个BeanPostProcessor实现类型的详细使用希望你自己完成从而真正体会BeanPostProcessor的用法

一张**图片relax你的思绪
20191203081016.png